import React from 'react';
import defaultFallbackUrl from "../../../../assets/img/placeholder.png"
import ReactDOM from 'react-dom/client';
import {Tooltip} from "antd";


export type ChartHtmlItem = {
  type: "img" | "custom",
  caption?: string,
  html?: string,
  src?: string
}

/**
 * 从参考文献引用信息中提取参考文献索引
 * 支持格式"[1,3,5-8,11,13-18,19]"
 * @param refSup
 * @return
 */
export function getRefSupIndexs(refSup: string) {
  if (!!refSup) {
    refSup = refSup.replace(/[\[|\]]/g, "").trim();
    const refIndexs = new Set<number>([]);
    refSup.split(",").forEach((e) => {
      if (isNaN(e as any)) {
        const start = parseInt(e.substring(0, e.indexOf("-")));
        const end = parseInt(e.substring(e.indexOf("-") + 1, e.length + 1));
        for (let i = start; i <= end; i++) {
          refIndexs.add(i);
        }
      } else {
        refIndexs.add(parseInt(e));
      }
    });
    return [...refIndexs].sort((a, b) => a - b);
  }
  return [];
}

/**
 * 为原生DOM的img元素创建fallback
 * @param imgElement
 */
export function createImgFallback(imgElement: HTMLImageElement, imgMapping: Record<string, string>) {
  // 检查是否已经绑定了 fallback 逻辑，避免重复绑定
  if (imgElement.hasAttribute('data-fallback-added')) {
    return;
  }
  let mappingSrc = imgMapping[imgElement.alt];

  //多个回退图片URL数组
  const fallbackUrls: string[] = [];

  if (!mappingSrc) {
    const mappingTestExtArray = ["jpg", "png"];
    for (const ext of mappingTestExtArray) {
      const extRegex: RegExp = new RegExp("\." + ext + "$", "i");
      if (!extRegex.test(imgElement.alt)) {
        const mSrc = imgMapping[imgElement.alt.replace(/(\.\w+)$/, '.' + ext)];
        if (!!mSrc) {
          mappingSrc = mSrc;
          break;
        }
      }
    }
  }
  if (!!mappingSrc) {
    imgElement.src = mappingSrc;
  }

  fallbackUrls.push(defaultFallbackUrl);

  // 定义当前尝试的 fallback 索引
  let currentFallbackIndex = 0;
  // 绑定 onerror 事件
  imgElement.onerror = () => {
    // 如果还有 fallback URL 可用
    if (currentFallbackIndex < fallbackUrls.length) {
      imgElement.src = imgMapping[fallbackUrls[currentFallbackIndex]] || fallbackUrls[currentFallbackIndex];
      currentFallbackIndex++;
    } else {
      // 所有 fallback URL 都加载失败，显示默认文本或图标
      imgElement.src = ""; // 清空 src 属性
      imgElement.alt = "无法加载图片"; // 设置 alt 文本
      imgElement.style.display = "none"; // 隐藏图片
      const fallbackText = document.createElement("span");
      fallbackText.textContent = "无法加载图片";
      fallbackText.className = "image-fallback-text";
      imgElement.parentNode?.insertBefore(fallbackText, imgElement.nextSibling);
      imgElement.onerror = null; // 停止监听
    }
  };

}

/**
 * 为原生DOM的sup元素创建Tooltip
 * @param options 配置项
 * @returns 销毁函数
 */
export function createSupTooltip(supElement: HTMLElement, references: NodeListOf<Element>) {
  // 类型守卫：确保传入的是有效的 HTMLElement
  if (!(supElement instanceof HTMLElement)) {
    console.error('无效的触发元素，必须是 HTMLElement');
    return;
  }
  // 避免重复处理
  if (supElement.hasAttribute('data-tooltip-added')) {
    return;
  }
  const supText = supElement.textContent; //输出格式为[2,10,13-15]
  const referenceIndexs = getRefSupIndexs(supText || "");
  // 根据 referenceIndexs 去references中取
  const tooltipContent = (
    referenceIndexs.map((index) => {
      return <div className={"row"} dangerouslySetInnerHTML={{__html: references[index - 1].innerHTML}}></div>
    })
  )

  supElement.setAttribute('data-tooltip-added', 'true');
  // 创建 Tooltip 容器
  const tooltipContainer = document.createElement('span');
  supElement.parentNode?.replaceChild(tooltipContainer, supElement);

  // 渲染 Tooltip 组件
  ReactDOM.createRoot(tooltipContainer).render(
    <Tooltip
      classNames={{
        body: "references-tooltip-body"
      }}
      title={tooltipContent} // 提示内容
      placement={"top"} // 默认位置
      arrow={true} // 是否显示箭头
      color={"#108ee9"}
      trigger={"click"}
      styles={{
        root: {
          maxWidth: 500,
        }
      }}
    >
      {/* 克隆原始 DOM 元素 */}
      {React.createElement(supElement.tagName, {
        ...Object.fromEntries(
          Array.from(supElement.attributes).map(attr => [attr.name, attr.value])
        ),
        dangerouslySetInnerHTML: {__html: supElement.innerHTML},
      })}
    </Tooltip>
  );
}
